﻿using Net.System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

namespace Net.FlowField
{
    // 编队信息
    public class Formation
    {
        public int Id;
        public int TeamType;
        public int Count;
        public RectInt BoundingRect;
        public Vector3 Target;
        public int MinX, MinZ;
        public int MaxX, MaxZ;
        public List<Vector3> Path = new();

        public void CalculatePath(Simulator simulator, Vector3 target)
        {
            var centerV2 = BoundingRect.center;
            if (centerV2.x < 0 || centerV2.x >= simulator.GridWidth || centerV2.y < 0 || centerV2.y >= simulator.GridHeight)
                return;
            if (target.x < 0 || target.x >= simulator.GridWidth || target.y < 0 || target.y >= simulator.GridHeight)
                return;
            var center = new Vector3(centerV2.x, 0, centerV2.y);
            Path = AStarPathfinder.FindPath(simulator, center, target);

            // 如果路径不为空，进一步优化路径
            if (Path != null && Path.Count > 0)
            {
                // 确保路径终点是目标点
                if (Path[Path.Count - 1] != target)
                {
                    Path.Add(target);
                }
            }
            else
            {
                Path = new() { target };
            }
        }

        public Vector3 GetNextPathPosition(int pathIndex)
        {
            if (Path == null || pathIndex >= Path.Count)
                return Target;
            return Path[pathIndex];
        }

        internal void InterlockedBounding(Vector3 position)
        {
            int x = (int)position.x;
            int z = (int)position.z;

            // 使用原子操作保证线程安全
            InterlockedMin(ref MinX, x);
            InterlockedMax(ref MaxX, x);
            InterlockedMin(ref MinZ, z);
            InterlockedMax(ref MaxZ, z);
        }

        // 原子操作辅助方法
        private void InterlockedMin(ref int target, int value)
        {
            int current;
            do
            {
                current = target;
            }
            while (value < current && Interlocked.CompareExchange(ref target, value, current) != current);
        }

        private void InterlockedMax(ref int target, int value)
        {
            int current;
            do
            {
                current = target;
            }
            while (value > current && Interlocked.CompareExchange(ref target, value, current) != current);
        }

        public override string ToString()
        {
            return $"Id: {Id} Team: {TeamType} Count: {Count} Rect: {BoundingRect}";
        }
    }
}